﻿using Cysharp.Threading.Tasks;
using Org.Xresloader.Pb;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using wProtobuf;

/// <summary>
/// 配置表管理器
/// </summary>
public partial class ConfigManager
{
    /// <summary>
    /// 256KB缓冲区
    /// </summary>
    private static MessageStream s_CachedStream = new MessageStream(1024 * 256);

    /// <summary>
    /// 配置管理字典
    /// </summary>
    private static Dictionary<Type, dynamic> s_ConfigDict = new Dictionary<Type, dynamic>();

    private static async UniTask<List<T>> LoadAsync<T>(string overrideName = null) where T : IMessage, new()
    {
        var configFileName = overrideName;
        if (string.IsNullOrEmpty(configFileName))
            configFileName = typeof(T).Name;
        try
        {
            var textAsset = await Addressables.LoadAssetAsync<TextAsset>(configFileName).Task;
            return LoadWithTextAsset<T>(textAsset);
        }
        catch (Exception ex)
        {
            Debug.LogError($"异步加载配置文件[{configFileName}]失败，错误信息：{ex}");
            return null;
        }
    }

    private static List<T> Load<T>(string overrideName = null) where T : IMessage, new()
    {
        var configFileName = overrideName;
        if (string.IsNullOrEmpty(configFileName))
            configFileName = typeof(T).Name;
        try
        {
            var textAsset = Addressables.LoadAssetAsync<TextAsset>(configFileName).WaitForCompletion();
            return LoadWithTextAsset<T>(textAsset);
        }
        catch (Exception ex)
        {
            Debug.LogError($"同步加载配置文件[{configFileName}]失败，错误信息：{ex}");
            return null;
        }
    }

    private static List<T> LoadWithTextAsset<T>(TextAsset textAsset) where T : IMessage, new()
    {
        s_CachedStream.WritePos = 0;
        s_CachedStream.ReadPos = 0;
        s_CachedStream.Write(textAsset.bytes);
        xresloader_datablocks datablocks = new xresloader_datablocks();
        datablocks.MergeFrom(s_CachedStream);
        List<T> configs = new List<T>();
        for (int i = 0; i < datablocks.data_block.Count; i++)
        {
            s_CachedStream.WritePos = 0;
            s_CachedStream.WriteBytes(datablocks.data_block[i]);
            s_CachedStream.ReadPos = 0;
            var config = new T();
            s_CachedStream.ReadMessage(config);
            configs.Add(config);
        }
        return configs;
    }

    /// <summary>
    /// 获取配置
    /// </summary>
    /// <typeparam name="T">配置表类型</typeparam>
    public static List<T> Get<T>() where T : IMessage, new()
    {
        var t = typeof(T);
        if (!s_ConfigDict.ContainsKey(t))
        {
            s_ConfigDict.Add(t, Load<T>());
        }
        s_ConfigDict.TryGetValue(t, out var configs);
        return (List<T>)configs;
    }
}